<?php

namespace xssg;

use Phalcon\Escaper;
use Phalcon\Tag;


class Start extends \Phalcon\Mvc\Application
{
    public function start(array $config)
    {
        $this->registerAutoloaders();
        $this->registerServices($config);
        $this->registerMultiple();
    }

    protected function registerAutoloaders()
    {

    }

    /**
     * 注册模块
     */
    protected function registerMultiple()
    {
        $this->registerModules([
            "home" => [
                "className" => "\\xssg\\home\\Module",
                'path' => XSSG_DIR . '/home/Module.php'
            ],
            "user" => [
                "className" => "\\xssg\\user\\Module"

            ],
        ]);
    }

    /**
     * 注册服务
     */
    protected function registerServices(array $configdata)
    {

        $di = new \Phalcon\Di();

        $di->set('tag', function () {
            $tag = new Tag();
            $tag->setDoctype(Tag::HTML5);
            return $tag;
        });
        $di->set('escaper', function () {
            $escaper = new Escaper();
            return $escaper;
        });


        $config = new \Phalcon\Config($configdata);
        //var_dump($di);
        $di->setShared("config", $config);
        $di = $this->registerEvent($di);
        $di = $this->registerDb($di);
        $di = $this->registerRouter($di);
        $di = $this->registerView($di);

        $di->set(
            "filter",
            function () {

                $filter = new \Phalcon\Filter();

                return $filter;
            }
        );


        // Registering a Http\Response
        $di->set("response", function () {
            return new \Phalcon\Http\Response();
        });

        // Registering a Http\Request
        $di->set("request", function () {
            return new \Phalcon\Http\Request();
        });

        $di->setShared(
            "session",
            function () {

                $session = new \Phalcon\Session\Adapter\Files();

                $session->start();

                return $session;
            }
        );

        // 注册一个调度器
        $di->set("dispatcher", function () {
            $dispatcher = new \Phalcon\Mvc\Dispatcher();
            $dispatcher->setActionSuffix("");
            $dispatcher->setControllerSuffix("");
            $dispatcher->setEventsManager(\Phalcon\Di::getDefault()->getShared("eventsManager"));
            return $dispatcher;
        });
        $this->setDI($di);
    }

    /**
     * 注册路由管理器 和 地址管理器
     */
    protected function registerView(\Phalcon\DiInterface $di)
    {
        // Register Volt as template engine with an anonymous function
        $di->set(
            "view",
            function () {

                $config = \Phalcon\Di::getDefault()->get("config");
                $view = new \Phalcon\Mvc\View();
                $view->setViewsDir($config->view->viewsdir);
                $view->registerEngines(
                    [
                        ".volt" => "voltService"
                    ]
                );

                $view->setEventsManager(\Phalcon\Di::getDefault()->getShared("eventsManager"));
                $view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_MAIN_LAYOUT);
                return $view;
            }
        );

        $di->set(
            "voltService", function ($view, $di) {
            $volt = new \xssg\sys\Volt();
            return $volt->start($view, $di);
        }
        );

        return $di;

    }

    /**
     * 注册路由管理器 和 地址管理器
     */
    protected function registerRouter(\Phalcon\DiInterface $di)
    {
        // Registering a router
        $di->set("router", function () {

            $router = new \Phalcon\Mvc\Router();
            $router->setDefaultModule("home");
            $router->add("/", [
                "module" => "home",
                "controller" => "index",
                "action" => "home"
            ])->setName("index");
            $router->add(
                "/:module/:controller/:action/:params",
                [
                    "module" => 1,
                    "controller" => 2,
                    "action" => 3,
                    "params" => 4
                ]
            );

            $router->add(
                "/:module/:controller/:action",
                [
                    "module" => 1,
                    "controller" => 2,
                    "action" => 3
                ]
            );
            return $router;

        });

        $di->set(
            "url",
            function () {

                $config = \Phalcon\Di::getDefault()->get("config");
                $url = new \Phalcon\Mvc\Url();
                $url->setBaseUri($config->baseurl);
                return $url;
            }
        );

        return $di;
    }

    /**
     * 注册事件管理器
     */
    protected function registerEvent(\Phalcon\DiInterface $di)
    {
        // Create an Events Manager
        $eventsManager = new \Phalcon\Events\Manager();
        //beforeExecuteRoute
        $eventsManager->attach("view", new \xssg\sys\middleware\View());
        $eventsManager->attach("router", new \xssg\sys\middleware\Router());
        $eventsManager->attach("dispatch", new \xssg\sys\middleware\Dispatcher());
        $eventsManager->attach("db", new \xssg\sys\middleware\Db());
        $eventsManager->attach("application", new \xssg\sys\middleware\Application());
        $this->setEventsManager($eventsManager);
        //Dispatcher
        $di->setShared("eventsManager", $eventsManager);
        return $di;
    }

    /**
     * 注册数据库组件
     */
    protected function registerDb(\Phalcon\DiInterface &$di)
    {
        //缓存
        $di->set("cache", function () {

            $config = \Phalcon\Di::getDefault()->get("config");
            // Create an Output frontend. Cache the files for 2 days
            $frontCache = new \Phalcon\Cache\Frontend\Data(
                [
                    "lifetime" => $config->cache->lifetime
                ]
            );
            $backend = "\\Phalcon\\Cache\\Backend\\" . $config->cache->backend;
            $cache = new $backend(
                $frontCache,
                $config->cache->options->toArray()
            );
            return $cache;
        });

        $di->set("db", function () {

            $config = \Phalcon\Di::getDefault()->get("config");
            $connection = new \Phalcon\Db\Adapter\Pdo\Mysql($config->db->toArray());
            return $connection;
        });

        $di->set(
            'modelsManager',
            new \Phalcon\Mvc\Model\Manager()
        );

        // Use the memory meta-data adapter or other
        $di->set(
            'modelsMetadata',
            new \Phalcon\Mvc\Model\Metadata\Memory()
        );


        return $di;
    }


}